package com.whfc.iot.mach.codec;

import com.whfc.common.util.MathUtil;
import com.whfc.common.util.VersionUtil;
import com.whfc.iot.mach.constant.MsgConst;
import com.whfc.iot.mach.entity.MachMsg0x01;
import com.whfc.iot.mach.entity.MachWorkState;
import com.whfc.iot.util.ByteUtil;
import com.whfc.iot.util.MsgDataCodecUtil;
import io.netty.buffer.ByteBuf;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/7/17 9:32
 */
public class MachMsgDataCodec0x01 implements MachMsgDataCodec<MachMsg0x01> {

    public static final double GPS_MULTIPLY = 100000 * 60D;

    private static final int WORK_STATE_NUM = 3;

    @Override
    public void decode(ByteBuf buf, MachMsg0x01 msg) {

        //读取工作状态(3个)
        List<MachWorkState> workStates = new ArrayList<>(WORK_STATE_NUM);
        for (int i = 0; i < WORK_STATE_NUM; i++) {
            //工作状态
            int workState = buf.readUnsignedByte();
            //时间
            Date time = MsgDataCodecUtil.readDateTime(buf);
            workStates.add(new MachWorkState(time, workState));
        }

        //电池状态
        int batteryState = buf.readUnsignedByte();

        //电池电量
        int batteryPower = buf.readUnsignedByte();

        //终端温度
        int deviceTemp = buf.readShort();

        //角度
        int rotationX = buf.readUnsignedShort();
        int rotationY = buf.readUnsignedShort();
        int rotationZ = buf.readUnsignedShort();

        //gps标志
        int gpsFlag = buf.readUnsignedByte();
        String lngFlag = MsgConst.EAST;
        String latFlag = MsgConst.NORTH;
        switch (gpsFlag) {
            case MsgConst.GPS_FLAG_N_E:
                lngFlag = MsgConst.EAST;
                latFlag = MsgConst.NORTH;
                break;
            case MsgConst.GPS_FLAG_N_W:
                lngFlag = MsgConst.WEST;
                latFlag = MsgConst.NORTH;
                break;
            case MsgConst.GPS_FLAG_S_E:
                lngFlag = MsgConst.EAST;
                latFlag = MsgConst.SOUTH;
                break;
            case MsgConst.GPS_FLAG_S_W:
                lngFlag = MsgConst.WEST;
                latFlag = MsgConst.SOUTH;
                break;
        }

        //经度
        int lngD = buf.readUnsignedByte();
        int[] lngMBytes = new int[3];
        lngMBytes[0] = buf.readUnsignedByte();
        lngMBytes[1] = buf.readUnsignedByte();
        lngMBytes[2] = buf.readUnsignedByte();
        int lngM = ByteUtil.low3ByteToInt(lngMBytes);
        double lng = lngD + (double) lngM / GPS_MULTIPLY;

        //纬度
        int latD = buf.readUnsignedByte();
        int[] latMBytes = new int[3];
        latMBytes[0] = buf.readUnsignedByte();
        latMBytes[1] = buf.readUnsignedByte();
        latMBytes[2] = buf.readUnsignedByte();
        int latM = ByteUtil.low3ByteToInt(latMBytes);
        double lat = latD + (double) latM / GPS_MULTIPLY;

        //油箱油位(废弃)
        int oilPos = buf.readUnsignedShort();
        double pressure = MathUtil.round(oilPos * 9.8 / 845, 6);
        //油箱压力
//        double pressure = (double) (buf.readUnsignedShort()) / 1000;
//        int oilPos = (int) (pressure * 845 / 9.8);

        //油箱温度
        int oilTemp = buf.readShort();

        //油箱状态
        int oilState = buf.readUnsignedByte();

        //油箱电量
        int oilPower = buf.readUnsignedByte();

        //主从机版本号
        int[] masterVerArr = new int[3];
        int[] slaveVerArr = new int[3];
        masterVerArr[0] = buf.readUnsignedByte();
        masterVerArr[1] = buf.readUnsignedByte();
        masterVerArr[2] = buf.readUnsignedByte();
        slaveVerArr[0] = buf.readUnsignedByte();
        slaveVerArr[1] = buf.readUnsignedByte();
        slaveVerArr[2] = buf.readUnsignedByte();
        String masterVer = VersionUtil.getHardwareVersion(masterVerArr);
        String slaveVer = VersionUtil.getHardwareVersion(slaveVerArr);

        //速度和海拔
        Double speed = null;
        Double elevation = null;
        if (buf.readableBytes() >= 6) {
            int speedVal = buf.readUnsignedShort();
            int elevationVal = buf.readInt();
            speed = (double) speedVal / 100;
            elevation = (double) elevationVal / 10;
        }

        msg.setWorkStates(workStates);
        msg.setBatteryState(batteryState);
        msg.setBatteryPower(batteryPower);
        msg.setDeviceTemp(MathUtil.round((double) deviceTemp / 100, 1));
        msg.setRotationX((double) rotationX / 10);
        msg.setRotationY((double) rotationY / 10);
        msg.setRotationZ((double) rotationZ / 10);
        msg.setLngFlag(lngFlag);
        msg.setLatFlag(latFlag);
        msg.setLngWgs84(lng);
        msg.setLatWgs84(lat);
        msg.setOilPos(oilPos);
        msg.setPressure(pressure);
        msg.setOilTemp(MathUtil.round((double) oilTemp / 100, 1));
        msg.setOilState(oilState);
        msg.setOilPower(oilPower);
        msg.setMasterVerArr(masterVerArr);
        msg.setMasterVer(masterVer);
        msg.setSlaveVerArr(slaveVerArr);
        msg.setSlaveVer(slaveVer);
        msg.setSpeed(speed);
        msg.setElevation(elevation);
    }

    @Override
    public void encode(ByteBuf buf, MachMsg0x01 msg) {

        //工作状态列表
        List<MachWorkState> workStates = msg.getWorkStates();
        for (MachWorkState machWorkState : workStates) {
            //终端工作状态
            buf.writeByte(machWorkState.getWorkState());
            //时间
            MsgDataCodecUtil.writeDateTime(buf, machWorkState.getTime());
        }

        //电池状态
        buf.writeByte(msg.getBatteryState());

        //电池电量
        buf.writeByte(msg.getBatteryPower());

        //终端温度
        buf.writeShort((int) (msg.getDeviceTemp() * 100));

        //角度
        buf.writeShort((int) (msg.getRotationX() * 10));
        buf.writeShort((int) (msg.getRotationY() * 10));
        buf.writeShort((int) (msg.getRotationZ() * 10));

        //GPS标志位(默认北纬/东经)
        int gpsFlag = 0x0F;
        if (MsgConst.NORTH.equals(msg.getLngFlag())) {
            gpsFlag &= 0xF0;
        }
        if (MsgConst.EAST.equals(msg.getLatFlag())) {
            gpsFlag &= 0x00;
        }
        buf.writeByte(gpsFlag);

        //经度
        int lngD = (int) msg.getLngWgs84();
        int lngM = (int) ((msg.getLngWgs84() - lngD) * GPS_MULTIPLY);
        buf.writeByte(lngD);
        buf.writeBytes(ByteUtil.extractLow3Byte(lngM));

        //纬度
        int latD = (int) msg.getLatWgs84();
        int latM = (int) ((msg.getLatWgs84() - latD) * GPS_MULTIPLY);
        buf.writeByte(latD);
        buf.writeBytes(ByteUtil.extractLow3Byte(latM));

        //油箱油位
        buf.writeShort(msg.getOilPos());

        //油箱压力
//        buf.writeShort((int) (msg.getPressure() * 1000));

        //油箱温度
        buf.writeShort((int) (msg.getOilTemp() * 100));

        //油箱状态
        buf.writeByte(msg.getOilState());

        //油箱电量
        buf.writeByte(msg.getOilPower());

        //主从机版本号
        int[] masterVerArr = VersionUtil.parseHardvareVersion(msg.getMasterVer());
        int[] slaveVerArr = VersionUtil.parseHardvareVersion(msg.getSlaveVer());
        for (int ver : masterVerArr) {
            buf.writeByte(ver);
        }
        for (int ver : slaveVerArr) {
            buf.writeByte(ver);
        }

        //速度和海拔
        if (msg.getSpeed() != null && msg.getElevation() != null) {
            int speed = (int) (msg.getSpeed() * 100);
            int elevation = (int) (msg.getElevation() * 10);
            buf.writeShort(speed);
            buf.writeInt(elevation);
        }

    }
}
